package com.app.stick.bind.service.impl;

import java.util.Date;
import java.util.List;

import com.app.common.constant.CacheConstants;
import com.app.common.core.redis.RedisCache;
import com.app.common.enums.DeleteEnum;
import com.app.common.enums.EnableEnum;
import com.app.common.enums.sick.PdiBindStatusEnum;
import com.app.common.exception.ServiceException;
import com.app.common.utils.SecurityUtils;
import com.app.common.utils.StringUtils;
import com.app.stick.bind.domain.vo.BizPatientBindDeviceVo;
import com.app.stick.bind.domain.vo.BizPatientDeviceListVo;
import com.app.stick.bind.domain.vo.BizPatientDeviceQueryVo;
import com.app.stick.device.domain.BizDeviceInfo;
import com.app.stick.device.mapper.BizDeviceInfoMapper;
import com.app.stick.monitor.domain.vo.BizMonitorCacheVo;
import com.app.stick.visit.domain.BizPatientVisit;
import com.app.stick.visit.mapper.BizPatientVisitMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.app.common.utils.DateUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.app.stick.bind.mapper.BizPatientDeviceInfoMapper;
import com.app.stick.bind.domain.BizPatientDeviceInfo;
import com.app.stick.bind.service.IBizPatientDeviceInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 患者和设备绑定信息Service业务层处理
 *
 * @author app
 * @date 2023-12-18
 */
@Service
public class BizPatientDeviceInfoServiceImpl extends ServiceImpl<BizPatientDeviceInfoMapper, BizPatientDeviceInfo> implements IBizPatientDeviceInfoService
{
    @Resource
    private BizPatientDeviceInfoMapper bizPatientDeviceInfoMapper;

    @Resource
    private BizPatientVisitMapper bizPatientVisitMapper;

    @Resource
    private BizDeviceInfoMapper bizDeviceInfoMapper;

    @Resource
    private RedisCache redisCache;

    /**
     * 查询患者和设备绑定信息
     *
     * @param pdiId 患者和设备绑定信息主键
     * @return 患者和设备绑定信息
     */
    @Override
    public BizPatientDeviceInfo selectBizPatientDeviceInfoByPdiId(String pdiId)
    {
        return bizPatientDeviceInfoMapper.selectById(pdiId);
    }

    /**
     * 查询患者和设备绑定信息列表
     *
     * @param queryVo 患者和设备绑定信息
     * @return 患者和设备绑定信息
     */
    @Override
    public List<BizPatientDeviceListVo> selectBizPatientDeviceInfoList(BizPatientDeviceQueryVo queryVo)
    {
        List<BizPatientDeviceListVo> patientDeviceListVos = bizPatientDeviceInfoMapper.selectBizPatientDeviceInfoList(queryVo);
        for (BizPatientDeviceListVo patientDeviceListVo : patientDeviceListVos) {
            boolean hasKey = redisCache.hasKey(CacheConstants.DEVICE_MONITOR_KEY + patientDeviceListVo.getDeviceCode());
            if (!hasKey) {
                continue;
            }
            BizMonitorCacheVo cacheVo = redisCache.getCacheObject(CacheConstants.DEVICE_MONITOR_KEY + patientDeviceListVo.getDeviceCode());
            if (StringUtils.isNotNull(cacheVo)) {
                patientDeviceListVo.setConStatus(EnableEnum.YES.getCode());
                patientDeviceListVo.setPdiCurDuration(cacheVo.getIntervalSeconds());
                patientDeviceListVo.setPdiCurElectricity(cacheVo.getPmiElectricity());
                patientDeviceListVo.setPdiCurTemperature(cacheVo.getPmiTemperature());
            }
        }
        return patientDeviceListVos;
    }

    /**
     * 新增患者和设备绑定信息
     *
     * @param bizPatientDeviceInfo 患者和设备绑定信息
     * @return 结果
     */
    @Override
    public int insertBizPatientDeviceInfo(BizPatientDeviceInfo bizPatientDeviceInfo)
    {
        bizPatientDeviceInfo.setCreateBy(SecurityUtils.getUserId());
        bizPatientDeviceInfo.setCreateTime(DateUtils.getNowDate());
        bizPatientDeviceInfo.setUpdateBy(SecurityUtils.getUserId());
        bizPatientDeviceInfo.setUpdateTime(DateUtils.getNowDate());
        return bizPatientDeviceInfoMapper.insert(bizPatientDeviceInfo);
    }

    /**
     * 修改患者和设备绑定信息
     *
     * @param bizPatientDeviceInfo 患者和设备绑定信息
     * @return 结果
     */
    @Override
    public int updateBizPatientDeviceInfo(BizPatientDeviceInfo bizPatientDeviceInfo)
    {
        bizPatientDeviceInfo.setUpdateBy(SecurityUtils.getUserId());
        bizPatientDeviceInfo.setUpdateTime(DateUtils.getNowDate());
        return bizPatientDeviceInfoMapper.updateBizPatientDeviceInfo(bizPatientDeviceInfo);
    }

    /**
     * 删除患者和设备绑定信息信息
     *
     * @param pdiId 患者和设备绑定信息主键
     * @return 结果
     */
    @Override
    public int deleteBizPatientDeviceInfoByPdiId(String pdiId)
    {
        BizPatientDeviceInfo bizPatientDeviceInfo = new BizPatientDeviceInfo();
        bizPatientDeviceInfo.setPdiId(pdiId);
        bizPatientDeviceInfo.setDelFlag(DeleteEnum.YES.getCode());
        bizPatientDeviceInfo.setUpdateBy(SecurityUtils.getUserId());
        bizPatientDeviceInfo.setUpdateTime(new Date());
        return bizPatientDeviceInfoMapper.updateById(bizPatientDeviceInfo);
    }

    /**
     * 患者和设备进行绑定
     * @param patientBindDeviceVo
     * @return int
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int bind(BizPatientBindDeviceVo patientBindDeviceVo) {
        //查询患者信息
        BizPatientVisit bizPatientVisit = bizPatientVisitMapper.selectById(patientBindDeviceVo.getVisitId());
        if (StringUtils.isNull(bizPatientVisit)) {
            throw new ServiceException("该患者信息不存在,无法进行绑定");
        }
        //查询设备信息
        BizDeviceInfo bizDeviceInfo = bizDeviceInfoMapper.selectOne(new LambdaQueryWrapper<BizDeviceInfo>()
                .eq(BizDeviceInfo::getDeviceCode, patientBindDeviceVo.getDeviceCode())
                .eq(BizDeviceInfo::getDelFlag, DeleteEnum.NO.getCode()));
        if (StringUtils.isNull(bizDeviceInfo)) {
            throw new ServiceException("该设备不存在,无法进行绑定");
        }

        if (EnableEnum.NO.getCode().equals(bizDeviceInfo.getDeviceStatus())) {
            throw new ServiceException("该设备已停用,无法进行绑定");
        }

        //判断该患者是否已经被绑定
        long patientBindNum = bizPatientDeviceInfoMapper.selectCount(new LambdaQueryWrapper<BizPatientDeviceInfo>()
                .eq(BizPatientDeviceInfo::getVisitId, patientBindDeviceVo.getVisitId())
                .eq(BizPatientDeviceInfo::getPdiBindStatus, PdiBindStatusEnum.BIND.getCode())
                .eq(BizPatientDeviceInfo::getDelFlag, DeleteEnum.NO.getCode()));
        if (patientBindNum > 0) {
            throw new ServiceException("该患者已经绑定设备,无需二次绑定");
        }
        //判断该设备是否已经绑定患者
        long deviceBindNum = bizPatientDeviceInfoMapper.selectCount(new LambdaQueryWrapper<BizPatientDeviceInfo>()
                .eq(BizPatientDeviceInfo::getDeviceCode, patientBindDeviceVo.getDeviceCode())
                .eq(BizPatientDeviceInfo::getPdiBindStatus, PdiBindStatusEnum.BIND.getCode())
                .eq(BizPatientDeviceInfo::getDelFlag, DeleteEnum.NO.getCode()));
        if (deviceBindNum > 0) {
            throw new ServiceException("该设备已经绑定患者,请先解绑");
        }
        BizPatientDeviceInfo bizPatientDeviceInfo = new BizPatientDeviceInfo();
        bizPatientDeviceInfo.setVisitId(patientBindDeviceVo.getVisitId());
        bizPatientDeviceInfo.setDeviceCode(patientBindDeviceVo.getDeviceCode());
        bizPatientDeviceInfo.setPdiCurDuration(0L);
        bizPatientDeviceInfo.setPdiAccDuration(0L);
        bizPatientDeviceInfo.setPdiBindTime(new Date());
        bizPatientDeviceInfo.setPdiBindStatus(PdiBindStatusEnum.BIND.getCode());
        bizPatientDeviceInfo.setDelFlag(DeleteEnum.NO.getCode());
        bizPatientDeviceInfo.setCreateBy(SecurityUtils.getUserId());
        bizPatientDeviceInfo.setCreateTime(new Date());
        int addPatientDevice = bizPatientDeviceInfoMapper.insert(bizPatientDeviceInfo);
        if (addPatientDevice <= 0) {
            throw new ServiceException("患者和设备绑定失败,请重试！");
        }
        //新增设备绑定次数
        BizDeviceInfo deviceInfo = new BizDeviceInfo();
        deviceInfo.setDeviceId(bizDeviceInfo.getDeviceId());
        deviceInfo.setDeviceNum(bizDeviceInfo.getDeviceNum() + 1);
        if (StringUtils.isNull(bizDeviceInfo.getDeviceFirstTime())) {
            deviceInfo.setDeviceFirstTime(new Date());
        }
        deviceInfo.setUpdateBy(SecurityUtils.getUserId());
        deviceInfo.setUpdateTime(new Date());
        int editDevice = bizDeviceInfoMapper.updateBizDeviceInfo(deviceInfo);
        if (editDevice <= 0){
            throw new ServiceException("患者和设备绑定修改设备信息失败,请重试！");
        }
        return addPatientDevice;
    }

    /**
     * 解除患者和设备绑定信息
     * @param pdiId
     * @return int
     */
    @Override
    public int unBind(String pdiId) {
        BizPatientDeviceInfo bizPatientDeviceInfo = new BizPatientDeviceInfo();
        bizPatientDeviceInfo.setPdiId(pdiId);
        bizPatientDeviceInfo.setPdiUnbindTime(new Date());
        bizPatientDeviceInfo.setPdiBindStatus(PdiBindStatusEnum.UNBIND.getCode());
        bizPatientDeviceInfo.setUpdateBy(SecurityUtils.getUserId());
        bizPatientDeviceInfo.setUpdateTime(new Date());
        return bizPatientDeviceInfoMapper.updateById(bizPatientDeviceInfo);
    }

    /**
     * 查询未绑定的患者列表
     * @param queryVo
     * @return {@link List}<{@link BizPatientDeviceListVo}>
     */
    @Override
    public List<BizPatientDeviceListVo> unBindPatient(BizPatientDeviceQueryVo queryVo) {
        return bizPatientDeviceInfoMapper.unBindPatient(queryVo);
    }

    /**
     * 查询未绑定的设备信息
     * @param bizDeviceInfo
     * @return {@link List}<{@link BizDeviceInfo}>
     */
    @Override
    public List<BizDeviceInfo> unBindDevice(BizDeviceInfo bizDeviceInfo) {
        return bizPatientDeviceInfoMapper.unBindDevice(bizDeviceInfo);
    }
}
